//
//  XCBlueToothModel.swift
//  RXSwiftDemo1
//
//  Created by mac on 2025/3/4.
//

import Foundation
import CoreBluetooth

class XCBlueToothModel: NSObject, Identifiable, Codable {
    var uuid: UUID?
    var peripheral: CBPeripheral?
    var macAddress: String? // 设备 MAC 地址
    var rssi: Int? // 信号强度
    var advData: [String: AdvDataValue]? // 广播数据
    var deviceName: String? // 设备名称
    var isConnected: Bool = false // 是否可连接（已被连接）
    var isCanConect: Bool = false
    
    var version: String? // 固件版本
    var versionName: String? // 固件版本名称
    var protocolVersion: Int = 0 // 协议版本
    var buildTime: String? // 构建版本时间，如 2021/08/24 14:01
    var voltage: String? // 电压值
    var battery: Int = 0 // 电量
    var isCharging: Bool = false // 是否在充电（非实时记录上次状态）
    var settingModel: DeviceSettingData? // 设备设置信息
    var azkarQuestModel: AzkarDataModel? // 赞念任务信息
    
    // 由于 CBPeripheral 不符合 Codable，需要自定义编码和解码
    enum CodingKeys: String, CodingKey {
        case macAddress, rssi, advData, deviceName, isConnected, isCanConect,uuid
        case version, versionName, protocolVersion, buildTime, voltage, battery, isCharging
        case settingModel, azkarQuestModel
    }
    
    override init() {
        super.init()
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        uuid = try container.decodeIfPresent(UUID.self, forKey: .uuid)
        macAddress = try container.decodeIfPresent(String.self, forKey: .macAddress)
        rssi = try container.decodeIfPresent(Int.self, forKey: .rssi)
        advData = try container.decodeIfPresent([String: AdvDataValue].self, forKey: .advData)
        deviceName = try container.decodeIfPresent(String.self, forKey: .deviceName)
        isConnected = try container.decode(Bool.self, forKey: .isConnected)
        isCanConect = try container.decode(Bool.self, forKey: .isCanConect)
        version = try container.decodeIfPresent(String.self, forKey: .version)
        versionName = try container.decodeIfPresent(String.self, forKey: .versionName)
        protocolVersion = try container.decode(Int.self, forKey: .protocolVersion)
        buildTime = try container.decodeIfPresent(String.self, forKey: .buildTime)
        voltage = try container.decodeIfPresent(String.self, forKey: .voltage)
        battery = try container.decode(Int.self, forKey: .battery)
        isCharging = try container.decode(Bool.self, forKey: .isCharging)
        settingModel = try container.decodeIfPresent(DeviceSettingData.self, forKey: .settingModel)
        azkarQuestModel = try container.decodeIfPresent(AzkarDataModel.self, forKey: .azkarQuestModel)
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(uuid, forKey: .uuid)
        try container.encode(macAddress, forKey: .macAddress)
        try container.encode(rssi, forKey: .rssi)
        try container.encode(advData, forKey: .advData)
        try container.encode(deviceName, forKey: .deviceName)
        try container.encode(isConnected, forKey: .isConnected)
        try container.encode(isCanConect, forKey: .isCanConect)
        try container.encode(version, forKey: .version)
        try container.encode(versionName, forKey: .versionName)
        try container.encode(protocolVersion, forKey: .protocolVersion)
        try container.encode(buildTime, forKey: .buildTime)
        try container.encode(voltage, forKey: .voltage)
        try container.encode(battery, forKey: .battery)
        try container.encode(isCharging, forKey: .isCharging)
        try container.encode(settingModel, forKey: .settingModel)
        try container.encode(azkarQuestModel, forKey: .azkarQuestModel)
    }
    
    func setAdvData(from dictionary: [String: Any]) {
        advData = dictionary.compactMapValues { value in
            AdvDataValue(from: value)
        }
    }
}

enum AdvDataValue: Codable {
    case number(NSNumber)
    case string(String)
    case data(Data)
    
    init?(from value: Any) {
        if let number = value as? NSNumber {
            self = .number(number)
        } else if let string = value as? String {
            self = .string(string)
        } else if let data = value as? Data {
            self = .data(data)
        } else {
            return nil
        }
    }
    
    // 实现 Decodable
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        
        if let numberValue = try? container.decode(Double.self) {
            self = .number(NSNumber(value: numberValue))
        } else if let stringValue = try? container.decode(String.self) {
            self = .string(stringValue)
        } else if let dataValue = try? container.decode(Data.self) {
            self = .data(dataValue)
        } else {
            throw DecodingError.typeMismatch(
                AdvDataValue.self,
                DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Unsupported type"
                )
            )
        }
    }
    
    // 实现 Encodable
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .number(let number):
            try container.encode(number.doubleValue)
        case .string(let string):
            try container.encode(string)
        case .data(let data):
            try container.encode(data)
        }
    }
}

enum DeviceLanguageType: Int,Codable {
    case arabic = 0    // 阿拉伯语
    case english = 1   // 英语
    case french = 2    // 法语
    case urdu = 3      // 乌尔都语
    case turkish = 4   // 土耳其语
    case chinese = 5   // 中文（一代删除）
    case indonesian = 6 // 印尼语
    case hindi = 7     // 印度语 （一代删除）
    case persian = 8   // 波斯语
    case german = 9    // 德语
    case thailand = 10 // 泰语（一代删除）
    case russian = 11  // 俄语
    case malay = 12    // 马来语
}


class DeviceSettingData: NSObject,Codable {
    var direction: Int? // 0: 正，1: 反
    var prayerSetDays: Int? // 祈祷时间设置天数
    var prayerSetTime: String? // 祈祷时间设置时的时间
    var counterRemindTime: Int? // 诵经提醒时间间隔，分钟
    var counterRemindStartTime: String? // 诵经提醒开始时间
    var counterRemindEndTime: String? // 诵经提醒结束时间
    var brightState: Int? // 0: 正常电量，1: 低电量
    var languageType: DeviceLanguageType? // 当前语言
    var isHasAzkarFunction: Bool? // 是否有赞念任务功能
    var isHasQuest: Bool? // 是否有目标赞念进行中
    var restTime: Int? // 息屏时间（默认10s, 包含6秒半熄屏和4秒暗屏）
    var is33Open: Bool? // 33N提醒（跟自定义互斥）
    var is100Open: Bool? // 100N提醒（跟自定义互斥）
    var customVibrate: Int? // 自定义震动提醒（跟33N和100N互斥）
    var homeType: Int? // 0：时间正常显示；1：倒计时时间显示
    var scBright: Int? // sc01de 亮度（5~255）
    var screenTime: Int? // SC01屏幕时间（5~300）
}


class AzkarDataModel: NSObject,Codable {
    var azkarCount: Int? // 可选的计数
    var azkarTag: Int? // 可选的标记
    var azkarGoals: Int? // 可选的目标
    var startTime: String? // 可选的开始时间
    var endTime: String? // 可选的结束时间
    var questType: Int? // 戒指端：0:无任务；1:有任务未开始；2:任务进行中；3:任务取消；4:任务完成 5:任务暂停
    var tick: String? // 可选的时间戳
    var tempStartTime: String? // 临时保存的开始时间，跟结束后读取的开始时间格式不同
}
